package server

/*******************************************************************************
Copyright:cloud
Author:cloudapex@126.com
Version:1.0
Date:2020-06-12
Description: api server
*******************************************************************************/
import (
	"context"
	"net/http"
	"permissions/api/login"
	"permissions/api/sys"
	"permissions/api/tool"
	"permissions/conf"
	"permissions/model"

	// "permissions/model"
	"time"

	"gitee.com/cloudapex/permit"
	"gitee.com/cloudapex/ulern/cto"
	"gitee.com/cloudapex/ulern/htp"
	"gitee.com/cloudapex/ulern/util"
	"github.com/gin-gonic/gin"
)

func init() { cto.Install("MC_Server", &server{}) }

type server struct {
	cto.ControlBase

	api http.Server
}

func (this *server) HandleInit() {
	this.ControlBase.HandleInit()

	permit.UseRdb(model.RDB(model.ERDB_Permt)) // 初始化中间库使用的redis连接

	this.initRouter()
	this.startServer()
}
func (this *server) HandleTerm() {
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()
	if err := this.api.Shutdown(ctx); err != nil {
		this.Error("api shut err:%v", err)
	}

	this.ControlBase.HandleTerm()
}

// ------------ internal
func (this *server) initRouter() {
	htp.Init(conf.Main.RunMode())

	r := gin.Default()
	this.api.Handler = r
	r.Use(htp.MH_Corss())
	r.Use(htp.MH_Heavier(1 * time.Second))

	// regist router
	this.menuRouter(r)
	this.roleRouter(r)
	this.groupRouter(r)
	this.userRouter(r)
	this.loginRouter(r)
	this.toolRouter(r)
}
func (this *server) startServer() {
	this.api.Addr = conf.Main.ListenAddr()

	if !conf.Main.UseTLS() {
		go func() {
			if err := this.api.ListenAndServe(); err != nil && err != http.ErrServerClosed {
				this.Fatal("Gin run err:%v", err)
			}
		}()
	} else {
		go func() {
			err := this.api.ListenAndServeTLS(util.ExePathJoin(conf.Main.TLSCrtFile()), util.ExePathJoin(conf.Main.TLSKeyFile()))
			if err != nil && err != http.ErrServerClosed {
				this.Fatal("Gin runTLS err:%v", err)
			}
		}()
	}

	util.Log.Info("Start api server on listen addr:%v, runMode:%q", conf.Main.ListenAddr(), conf.Main.RunMode())
}

// ----- router groups
func (this *server) menuRouter(r *gin.Engine) {
	gr := r.Group("menu")
	gr.Use(htp.MH_JWTAuthed((*model.CustomClaims)(nil), model.SignKey))
	gr.Use(permit.MH_Permit(model.RDB(model.ERDB_Permt), conf.Main.AdminIds()))
	gr.GET("list", // 菜单列表
		func(c *gin.Context) { htp.Service(c, &sys.MenuList{}) })
	gr.GET("tree", // 菜单树表
		func(c *gin.Context) { htp.Service(c, &sys.MenuTree{}) })
	gr.POST("add", // 新增菜单
		func(c *gin.Context) { htp.Service(c, &sys.MenuAdd{}) })
	gr.POST("upd", // 编辑菜单
		func(c *gin.Context) { htp.Service(c, &sys.MenuUpd{}) })
	gr.POST("del", // 删除菜单
		func(c *gin.Context) { htp.Service(c, &sys.MenuDel{}) })
}
func (this *server) roleRouter(r *gin.Engine) {
	gr := r.Group("role")
	gr.Use(htp.MH_JWTAuthed((*model.CustomClaims)(nil), model.SignKey))
	gr.Use(permit.MH_Permit(model.RDB(model.ERDB_Permt), conf.Main.AdminIds()))
	gr.GET("list", // 角色列表
		func(c *gin.Context) { htp.Service(c, &sys.RoleList{}) })
	gr.GET("labs", // 角色简列
		func(c *gin.Context) { htp.Service(c, &sys.RoleLabs{}) })
	gr.POST("add", // 新增角色
		func(c *gin.Context) { htp.Service(c, &sys.RoleAdd{}) })
	gr.POST("upd", // 编辑角色
		func(c *gin.Context) { htp.Service(c, &sys.RoleUpd{}) })
	gr.POST("del", // 删除角色
		func(c *gin.Context) { htp.Service(c, &sys.RoleDel{}) })
	gr.GET("choice", // 获取角色权限
		func(c *gin.Context) { htp.Service(c, &sys.RoleChoice{}) })
	gr.POST("choose", // 修改角色权限
		func(c *gin.Context) { htp.Service(c, &sys.RoleChoose{}) })
}
func (this *server) groupRouter(r *gin.Engine) {
	gr := r.Group("group")
	gr.Use(htp.MH_JWTAuthed((*model.CustomClaims)(nil), model.SignKey))
	gr.Use(permit.MH_Permit(model.RDB(model.ERDB_Permt), conf.Main.AdminIds()))
	gr.GET("list", // 用户组列表
		func(c *gin.Context) { htp.Service(c, &sys.GroupList{}) })
	gr.GET("tree", // 用户组树表
		func(c *gin.Context) { htp.Service(c, &sys.GroupTree{}) })
	gr.POST("add", // 新增用户组
		func(c *gin.Context) { htp.Service(c, &sys.GroupAdd{}) })
	gr.POST("upd", // 编辑用户组
		func(c *gin.Context) { htp.Service(c, &sys.GroupUpd{}) })
	gr.POST("del", // 删除用户组
		func(c *gin.Context) { htp.Service(c, &sys.GroupDel{}) })
	gr.GET("choice", // 获取用户组权限
		func(c *gin.Context) { htp.Service(c, &sys.GroupChoice{}) })
	gr.POST("choose", // 修改用户组权限
		func(c *gin.Context) { htp.Service(c, &sys.GroupChoose{}) })
}
func (this *server) userRouter(r *gin.Engine) {
	gr := r.Group("user")
	gr.Use(htp.MH_JWTAuthed((*model.CustomClaims)(nil), model.SignKey))
	gr.Use(permit.MH_Permit(model.RDB(model.ERDB_Permt), conf.Main.AdminIds()))

	gr.GET("list", // 用户列表
		func(c *gin.Context) { htp.Service(c, &sys.UserList{}) })
	gr.POST("add", // 新增用户
		func(c *gin.Context) { htp.Service(c, &sys.UserAdd{}) })
	gr.POST("upd", // 编辑用户
		func(c *gin.Context) { htp.Service(c, &sys.UserUpd{}) })
	gr.POST("sta", // 更改用户状态
		func(c *gin.Context) { htp.Service(c, &sys.UserSta{}) })
	gr.POST("del", // 删除用户
		func(c *gin.Context) { htp.Service(c, &sys.UserDel{}) })
	gr.GET("choice", // 获取用户的组织角色
		func(c *gin.Context) { htp.Service(c, &sys.UserChoice{}) })
	gr.POST("choose", // 修改用户的组织角色
		func(c *gin.Context) { htp.Service(c, &sys.UserChoose{}) })
	gr.GET("permis", // 获取用户的权限信息
		func(c *gin.Context) { htp.Service(c, &sys.UserPermis{}) })
}
func (this *server) loginRouter(r *gin.Engine) {
	gr := r.Group("login")
	gr.Use(htp.MH_JWTAuthed((*model.CustomClaims)(nil), model.SignKey))

	gr.GET("permis", // 登陆时权限列表(UI)
		func(c *gin.Context) { htp.Service(c, &login.UIPermis{}) })
}
func (this *server) toolRouter(r *gin.Engine) {
	gr := r.Group("tool")
	gr.Use(htp.MH_JWTAuthed((*model.CustomClaims)(nil), model.SignKey))
	gr.Use(permit.MH_Permit(model.RDB(model.ERDB_Permt), conf.Main.AdminIds()))

	gr.GET("user_permis", // 获取用户的权限信息
		func(c *gin.Context) { htp.Service(c, &sys.UserPermis{}) })
	gr.GET("cache_role", // 角色缓存数据
		func(c *gin.Context) { htp.Service(c, &tool.CacheRole{}) })
	gr.GET("cache_route", // 路由缓存数据
		func(c *gin.Context) { htp.Service(c, &tool.CacheRoute{}) })
	gr.POST("cache_reset", // 重置路由缓存数据
		func(c *gin.Context) { htp.Service(c, &tool.CacheReset{}) })
}
